
#include <stdint.h>
#include "apitrans.h"
#include "config.h"
#include "result.h"
#include "devapi.h"

/*
******************************************************************************************
**	local referenced extern function and variables 
******************************************************************************************
*/

/*
******************************************************************************************
**	local referenced macro defines & type defines
******************************************************************************************
*/

/*
******************************************************************************************
**	local function prototype
******************************************************************************************
*/

/*
******************************************************************************************
**	global variables 
******************************************************************************************
*/

/*
******************************************************************************************
**	Implementation functions 
******************************************************************************************
*/
static int api_icc_status(unsigned char *cmd, int len)
{
	uint16_t ret;
	uint8_t status[5]={0};
	uint8_t offset = 0;
	int status_len = 0;
	if(len != 0){
		ret = ERROR_PARAM;
		memcpy(cmd, &ret, 2);
		return -1;
	}
	ret = DEAL_SUCCESS;
	icc_status(status, &status_len );
	memcpy(cmd+offset,&ret,2);
	offset += 2;
	memcpy(cmd+offset,status,5);
	offset += 5;
	return offset;
}

static int api_icc_pwrup(unsigned char *cmd, int len)
{
	uint16_t ret = DEAL_SUCCESS;
	uint8_t cardno = 0;
	uint8_t out[256]={0};
	int outlen = 0;
	uint16_t offset = 0;
    int tmp;
    
	cardno = cmd[offset++];
    
	if(offset != len){
		ret = ERROR_PARAM;
		memcpy(cmd, &ret, 2);
		return -1;
	}
    
	if(cardno >= 5){
		ret = ERROR_ICC_PAR;
		memcpy(cmd,&ret,2);
		return -1;
	}
    
	if((tmp = icc_power_up( cardno, out, &outlen))<0){
     
		ret = ERROR_ICC_POWERUP;
		memcpy(cmd,&ret,2);
		return -1;
	}
	offset = 0;
	memcpy(cmd+offset,&ret,2);
	offset += 2;
	DectoBCD(outlen,cmd+offset,2);
	offset += 2;
	memcpy(cmd+offset,out,outlen);
	offset += outlen;
	return offset;
}

static int api_icc_apdu(unsigned char *cmd, int len)
{
	uint16_t ret = DEAL_SUCCESS;
	uint8_t cardno = 0;
	uint8_t in[MAX_SIZE]={0};
	uint8_t out[MAX_SIZE]={0};
	int outlen = 0;
	int inlen = 0;
	uint16_t offset = 0;
	cardno = cmd[offset];
	offset += 1;
	inlen = BCDtoDec(cmd+offset,2);
	offset += 2;
	if(inlen > MAX_SIZE){
		ret = ERROR_PARAM;
		memcpy(cmd, &ret, 2);
		return -1;
	}
	memcpy(in,cmd+offset,inlen);
	offset += inlen;
	if(offset != len || (inlen > MAX_SIZE)){
		ret = ERROR_PARAM;
		memcpy(cmd, &ret, 2);
		return -1;
	}	
	if(cardno >= 5){
		ret = ERROR_ICC_PAR;
		memcpy(cmd,&ret,2);
		return -1;
	}
	if(icc_send_apdu(cardno,in,inlen,out,&outlen)<0){
		ret = ERROR_ICC_APDU;
		memcpy(cmd,&ret,2);
		return -1;
	}
	offset = 0;
	memcpy(cmd+offset,&ret,2);
	offset += 2;
	DectoBCD(outlen,cmd+offset,2);
	offset += 2;
	memcpy(cmd+offset,out,outlen);
	offset += outlen;
	return offset;


}

static int api_icc_pwrdown(unsigned char *cmd, int len)
{
	uint16_t ret = DEAL_SUCCESS;
	uint8_t cardno = 0;
	uint8_t offset = 0;

	cardno = cmd[offset++];
	if(offset != len){
		ret = ERROR_PARAM;
		memcpy(cmd, &ret, 2);
		return -1;
	}
	if(cardno >= 5){
		ret = ERROR_ICC_PAR;
		memcpy(cmd,&ret,2);
		return -1;
	}
	if (icc_power_down(cardno) < 0) {
  
		ret = ERROR_ICC_POWERDOWN;
		memcpy(cmd,&ret,2);
		return  -1;
	}
	offset = 0;
	memcpy(cmd+offset,&ret,2);
	offset += 2;
	return offset;
}



static func_t icc_fun[] = {
	NULL, api_icc_status,api_icc_pwrup,api_icc_apdu,api_icc_pwrdown
};
#define ICC_NUM 4
int cmd_icccard(uint8_t cmd,uint8_t *buf,int len)
{
	if(cmd < 0x01 || cmd > FUN_SIZE(icc_fun))
		return -5;
	return icc_fun[(int)cmd]((uint8_t*)buf,len);
}


